/*
 * hujiangshui
 * 2017.8.22
 * 
 */

import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class MptcpTcpServerSocket {
	private static String serverIP;
	private static int port;
	
	
	public static void main(String[] args) {
		System.out.println("demo, start tcp uplink throughput test tcp socket server command: java -jar mptcp_server_socket.jar serverIp:serverPort 0 ");
		System.out.println("demo, start tcp downlink throughput test tcp socket server command: java -jar mptcp_server_socket.jar serverIp:serverPort 1 ");
		System.out.println("demo, start tcp rtt test tcp socket server command: java -jar mptcp_server_socket.jar serverIp:serverPort 2 ");
		
		if(args.length == 2){
			System.out.println("params: "+args[0]+"   "+args[1]);
			
			String ip = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}:\\d{0,5}"; 
			Pattern pattern = Pattern.compile(ip);
	        Matcher matcher = pattern.matcher(args[0]);
	        if(!matcher.matches()){
	        	System.out.println("failed, serverIp:serverPort format error,please edit like 127.0.0.1:80 ");
	        	return;
	        }
	        String[] serverSettings = args[0].split(":");
	        serverIP = serverSettings[0].trim();
	        try{
	        	port  = Integer.parseInt(serverSettings[1].trim());
	        }catch(Exception e){
	        	System.out.println("failed, serverPort format error,please use int number ");
	        	return;
	        }
			
			if(args[1] !=null && args[1].length()!=0 && "0".equals(args[1])){
				startReadServerSocket();
			}
			
			if(args[1] !=null && args[1].length()!=0 && "1".equals(args[1])){
				startWriteServerSocket();
			}
			
			if(args[1] !=null && args[1].length()!=0 && "2".equals(args[1])){
				startRttServerSocket();
			}
		}
		
		
		
		
	}
	
	
	public static void startRttServerSocket(){
		ServerSocket serverSocket=null;

		byte[] bytesBuffer = new byte[1024];
		
		try {
			serverSocket = new ServerSocket(); 
			System.out.println("new tcp server socket");
			serverSocket.bind(new InetSocketAddress(serverIP,port));
			System.out.println("new tcp server socket bind success");
			
			while(true){
						
					System.out.println("wait for connect...");
					//tcp connection
					Socket connection=serverSocket.accept();
				
					System.out.println("new connect from client, wait for client send data");
					
					
					
					new Thread(new Runnable() {
						
						@Override
						public void run() {
							DataInputStream inputObj = null;
							OutputStream outputStream = null;
							try {
								System.out.println("new a thread to deal with the connection, read data and send data");
								//read client message
								inputObj = new DataInputStream(connection.getInputStream());
								
								//send message to client
								outputStream = connection.getOutputStream();
								
								while(true){
								
								
										inputObj.read(bytesBuffer);
										System.out.println("read num:"+new String(bytesBuffer));
										outputStream.write(bytesBuffer, 0,bytesBuffer.length);
					                	outputStream.flush();
					                	System.out.println("send bytes to client");
									
								}
							} catch (Exception e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
								try{
									if (connection!=null) {
										connection .close();
									}
									if (inputObj!=null) {
										inputObj .close();
									}
									if (outputStream!=null) {
										outputStream .close();
									}
								}catch(Exception e1){
									e1.printStackTrace();
								}
							}
						}
					}).start();
					
					
					


			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try{
				
				if (serverSocket!=null) {
					serverSocket.close();
				}
			}catch(IOException e){
				e.printStackTrace();
			}

		}
	}
	
	
	/**
	 * start server
	 */
	public static void startReadServerSocket(){
		ServerSocket serverSocket=null;
		Socket connection = null;
		try {
			serverSocket = new ServerSocket(); 
			serverSocket.bind(new InetSocketAddress(serverIP,port));
		
			while(true){
				System.out.println("read server start,wait for connect...");
				
				//tcp connection
				connection=serverSocket.accept();
				
				System.out.println("****received message from client******");
				
				//read client message
				readMessageFromClient(connection);
				
				System.out.println("****received message from client end******");
				
				connection.close();

			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if (connection!=null) {
				try{
					connection.close();	
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			if (serverSocket!=null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
	}

	
	/**
	 * start server
	 */
	public static void startWriteServerSocket(){
		ServerSocket serverSocket=null;
		Socket connection = null;
	
		try {
			serverSocket = new ServerSocket(); 
			serverSocket.bind(new InetSocketAddress(serverIP,port));
		
			while(true){
				System.out.println("start write server wait for connect...");
					
				//tcp connection
				connection=serverSocket.accept();
				
				System.out.println("****send message to client******");
				
				//write messge to client
				writeMsgToClient(connection);
			
				System.out.println("****send message to client end******");

				connection.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if (connection!=null) {
				try{
					connection.close();	
				}catch(IOException e){
					e.printStackTrace();
				}
				
			}
			if (serverSocket!=null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
	}
	
	/**
	 * read message and store the bytes to file
	 */
	private static void readMessageFromClient(Socket connection) throws IOException {
		DataInputStream inputObj = new DataInputStream(connection.getInputStream());
		byte[] bytesBuffer = new byte[1024*8];
		int readBytesNum = 0;
		while(true){
			readBytesNum = inputObj.read(bytesBuffer);
			if(connection.isClosed()){
				break;
			}
//			System.out.println("read num:"+readBytesNum);
		}
		System.out.println("read data from client finished");
	}

	/**
	 * write messge
	 * @param outputStream
	 * @param string
	 */
	private static void writeMsgToClient(Socket connection) throws IOException {
		OutputStream outputStream = null;
		try{
			byte[] tempByte = new byte[1024 * 8];
    		for(int i=0;i<tempByte.length;i++){
    			tempByte[i]='a';
    		}
    		outputStream = connection.getOutputStream();
            while (true) {
            	outputStream.write(tempByte, 0, tempByte.length);
            	outputStream.flush();
            	//System.out.println("send bytes:"+readBytes);
            	if(connection.isClosed()){
            		break;
            	}
                
            }
			
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			System.out.println("output stream closed");
			outputStream.close();
		}
	}
}

